home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / usrlib / src / tiff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-17  |  7.7 KB  |  315 lines

  1. /*
  2.     tiff.c
  3.  
  4.     TIFF画像セーブ・ロード関数
  5.     (200KB程度のメモリが必要)
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <winb.h>
  12. #include <te.h>
  13. #include <fntb.h>
  14. #include <gui.h>
  15. #include <egb.h>
  16. #include <wgb.h>
  17. #include <msdos.cf>
  18. #include <malloc.h>
  19.  
  20. #include <ryosuke.h>
  21. #include <tifflib.h>
  22. #include <msdos.cf>
  23. #include <usrlib.h>
  24.  
  25. #define    DATABUF        (32*1024)
  26. #define    IMAGEBUF    (16*1024)
  27. #define    WORKBUF        _max(DECOMP_WORK_SIZE,COMP_WORK_SIZE)
  28.  
  29. static char *databuf = NULL;
  30. static char *imagebuf = NULL;
  31. static char *workbuf = NULL;
  32. static int x,y;
  33. static FILE *fp;
  34. static    TIFFinfo    tiffinfo;
  35.  
  36.  
  37. /*--------------------------------------------------------*/
  38. /*                   作業用メモリの確保                   */
  39. /*--------------------------------------------------------*/
  40.  
  41.  
  42. int TIFFinitwork()
  43. // 返値 0=正常終了  -1=メモリ不足
  44. {
  45.     if (databuf == NULL) {        // 作業用メモリ領域の確保
  46.         if ((databuf = malloc(DATABUF+IMAGEBUF+WORKBUF)) == NULL)
  47.             return -1;
  48.         imagebuf = databuf + DATABUF;
  49.         workbuf = imagebuf + IMAGEBUF;
  50.     }
  51.     return 0;
  52. }
  53.  
  54. int TIFFinitworkGUI()
  55. // 返値 0=正常終了  -1=メモリ不足
  56. {
  57.     if (databuf == NULL) {        // 作業用メモリ領域の確保
  58.         if ((databuf = TL_calloc(1,DATABUF+IMAGEBUF+WORKBUF)) == NULL)
  59.             return -1;
  60.         imagebuf = databuf + DATABUF;
  61.         workbuf = imagebuf + IMAGEBUF;
  62.     }
  63.     return 0;
  64. }
  65.  
  66.  
  67. /*--------------------------------------------------------*/
  68. /*                 TIFF データの読み出し                  */
  69. /*--------------------------------------------------------*/
  70.  
  71. static int load_x0, load_y0;
  72.  
  73. static int input_data(char *buf, int size)
  74. {
  75.     fread(buf,1,size,fp);
  76.     return 0;
  77. }
  78.  
  79. static int output_image(char *buf, int lofs, int lines)
  80. {
  81.     struct { char *buf;  short sel, sx,sy,ex,ey; } p;
  82.     p.buf = buf;            p.sel = getds();
  83.     p.sx = load_x0;            p.ex = load_x0 + x - 1;
  84.     p.sy = load_y0 + lofs;    p.ey = load_y0 + lofs + lines - 1;
  85.     EGB_putBlock( EGB_work, 0, (char*)&p );
  86.     return 0;
  87.     /*
  88.         if (!(_wrtpage & 0x80)) {
  89.             struct { char *buf;  short sel, sx,sy,ex,ey; } p;
  90.             p.buf = buf;            p.sel = getds();
  91.             p.sx = load_x0;            p.ex = load_x0 + x - 1;
  92.             p.sy = load_y0 + lofs;    p.ey = load_y0 + lofs + lines - 1;
  93.             EGB_putBlock(EGB_work, 0, (char*)&p);
  94.             return 0;
  95.         } else {
  96.             gputblk(buf, load_x0, load_y0+lofs, x, lines, 0);
  97.             return 0;
  98.         }
  99.     */
  100. }
  101.  
  102. static int (*putimagefunc)() = NOFNCint;
  103.  
  104. void TIFFload_putimagefunc(int (*func)())
  105. {
  106.     putimagefunc = func;
  107. }
  108.  
  109. int TIFFload(char *fname, int x0, int y0)
  110. // 返値  0=成功  -1=失敗
  111. {
  112.     if (TIFFinitwork() != 0)
  113.         return -1;
  114.     load_x0 = x0;
  115.     load_y0 = y0;
  116.     if ((fp = fopen(fname,"rb")) == NULL)
  117.         return -1;
  118.     fread(databuf,1,DATABUF,fp);        // ヘッダの読み出し
  119.     if (TIFF_getHead(databuf,DATABUF) < 0)
  120.         goto END;
  121.     int pixelsize;
  122.     int comp,fill;
  123.     long strip,clut;
  124.     if ((pixelsize = TIFF_checkMode(&x,&y,&comp,&fill,&strip,&clut)) < 0)
  125.         goto END;
  126.     if (pixelsize == 24)
  127.         goto END;
  128.     if (putimagefunc == NOFNCint)
  129.         TIFF_setLoadFunc(output_image, input_data);
  130.     else
  131.         TIFF_setLoadFunc(putimagefunc, input_data);
  132.     int img_xlen, img_ylen;
  133.     img_xlen = (pixelsize==4 ? ((x+7) & 0xfffffff8) : x);
  134.     img_ylen = IMAGEBUF / ((img_xlen*pixelsize+7)/8);
  135.     if (clut!=0) {
  136.         char plt[256*8+4];
  137.         TIFF_getPal(plt);
  138.         EGB_palette(EGB_work, 0, plt);
  139.     }
  140.     TIFF_loadImage(pixelsize,x,y,strip,fill,comp,
  141.                    imagebuf,img_xlen,img_ylen,workbuf);
  142. END:
  143.     fclose(fp);
  144.     // TIFF情報構造体の更新
  145.     {
  146.         tiffinfo.xlen = x;
  147.         tiffinfo.ylen = y;
  148.     }
  149.     return 0;
  150. }
  151.  
  152.  
  153. /*--------------------------------------------------------*/
  154. /*                 TIFF データの書き込み                  */
  155. /*--------------------------------------------------------*/
  156.  
  157.  
  158. static int save_x1, save_y1, save_xlen, save_ylen;
  159.  
  160.  
  161. static int output_data(char *buf, long size)
  162. {
  163.     if (fwrite(buf,1,size,fp) < size)
  164.         return -1;
  165.     return 0;
  166. }
  167.  
  168.  
  169. static int input_image(char *buf,int lofs,int lines)
  170. {
  171.     struct { char *buf;  short sel, sx,sy,ex,ey; } p;
  172.     p.buf = buf;    p.sel = getds();
  173.     p.sx = save_x1;            p.ex = save_x1 + save_xlen - 1;
  174.     p.sy = save_y1 + lofs;    p.ey = save_y1 + lofs + lines - 1;
  175.     EGB_getBlock(EGB_work, (char*)&p);
  176.     return 0;
  177. }
  178.  
  179.  
  180. #define    NOFNC    ((int (*)())0)
  181.  
  182.  
  183. static int (*getimagefunc)() = NOFNCint;
  184.  
  185.  
  186. void TIFFsave_getimagefunc(int (*func)())
  187. {
  188.     getimagefunc = func;
  189. }
  190.  
  191.  
  192. int TIFFsave(char *fname, int x1,int y1,int xlen,int ylen, bool compress)
  193. // 返値  0=成功  -1=画面モード/ファイル名の間違い
  194. //                 -2=メモリ不足  -3=ディスク領域不足  -4=get関数エラー
  195. {
  196.     if (TIFFinitwork() != 0)
  197.         return -2;
  198.     save_x1 = x1;
  199.     save_y1 = y1;
  200.     save_xlen = xlen;
  201.     save_ylen = ylen;
  202.     int pixelsize,headsize;
  203.     char _palet[256*8+4],*palet;
  204.     palet = NULL;
  205.     headsize = 512;
  206.  
  207.     int scrmod, wrtpage;
  208.     wrtpage = EGB_getWritePage(EGB_work, getds());
  209.     if ( wrtpage == 0 )
  210.         scrmod = ( EGB_getResolution( NULL, NULL ) & 255 );
  211.     else
  212.         scrmod = ( (EGB_getResolution( NULL, NULL ) >> 8) & 255 );
  213.  
  214.     if (scrmod == 3 || scrmod == 4)
  215.     {
  216.         pixelsize = 4,  x = 640, y = 480;
  217.         EGB_getPalette(wrtpage, _palet);
  218.         palet = _palet;
  219.     }
  220.     else if (5 <= scrmod && scrmod <= 8)
  221.         pixelsize = 16,    x = 256, y = 240;
  222.     else if (9 <= scrmod && scrmod <= 11)
  223.         pixelsize = 16, x = 320, y = 240;
  224.     else if (12 <= scrmod && scrmod <= 14)
  225.     {
  226.         pixelsize = 8,  x = 640, y = 480;
  227.         EGB_getPalette(wrtpage, _palet);
  228.         palet = _palet;
  229.         headsize = 2048;
  230.     }
  231.     else if (15 <= scrmod && scrmod <=18)
  232.         pixelsize = 16,  x = 512, y = 480;
  233.     else
  234.         return -1;
  235.     //
  236.     // (1) ファイルをオープンし、ヘッダのサイズ分シークする。
  237.     //     ヘッダサイズ : 256色モード=2048 bytes  その他モード=512 bytes
  238.     if ((fp = fopen(fname,"wb")) == NULL)
  239.         return -1;
  240.     if (fwrite(databuf,1,headsize,fp) < headsize)
  241.         { fclose(fp);  return -3; }
  242.     //
  243.     // (2) 画面データの取り出しルーチンと、ファイルへ書き出すルーチンを登録
  244.     if (getimagefunc == NOFNCint)
  245.         TIFF_setSaveFunc(output_data,input_image);
  246.     else
  247.         TIFF_setSaveFunc(output_data,getimagefunc);
  248.     //
  249.     // (3) TIFF のセーブルーチンをコールする
  250.     int img_xlen,img_ylen;
  251.     img_xlen = (pixelsize==4 ? ((save_xlen+7) & 0xfffffff8) : save_xlen);
  252.     img_ylen = IMAGEBUF / ((img_xlen*pixelsize+7)/8);
  253.     int cmp_size;
  254.     cmp_size = TIFF_saveImage(pixelsize, save_xlen, save_ylen, (compress? 5:1),
  255.                               databuf, DATABUF, imagebuf, img_xlen, img_ylen,
  256.                               workbuf);
  257.     if (cmp_size == -1)
  258.         { fclose(fp);  return -4; }
  259.     else if (cmp_size == -2)
  260.         { fclose(fp);  return -3; }
  261.     //
  262.     // (4) ヘッダ情報をつくる
  263.     TIFF_setHead(databuf,pixelsize,save_xlen,save_ylen,
  264.                  (compress? cmp_size: 0), palet);
  265.     //
  266.     // (5) ファイルを先頭にシークして、ヘッダを書き出し、クローズ
  267.     fflush(fp);
  268.     long nowfp;
  269.     nowfp = ftell(fp);
  270.     rewind(fp);
  271.     if (fwrite(databuf,1,headsize,fp) < headsize)
  272.         { fclose(fp);  return -3; }
  273.     fflush(fp);
  274.     fseek(fp,nowfp,SEEK_SET);
  275.     fclose(fp);
  276.     // TIFF情報構造体の更新
  277.     {
  278.         tiffinfo.xlen = save_xlen;
  279.         tiffinfo.ylen = save_ylen;
  280.     }
  281.     return 0;
  282. }
  283.  
  284.  
  285. /*--------------------------------------------------------*/
  286. /*         TIFF データファイルに関する情報を得る          */
  287. /*--------------------------------------------------------*/
  288.  
  289.  
  290. int TIFFgetinfo(char *fname, TIFFinfo *info)
  291. // 返値  0=正常終了
  292. //      -1=ファイルが存在しない
  293. //      -2=TIFF形式ではない
  294. //      -3=メモリが足りない
  295. {
  296.     if (TIFFinitwork() != 0)
  297.         return -3;
  298.     if ((fp = fopen(fname,"rb")) == NULL)
  299.         return -1;
  300.     fread(databuf,1,DATABUF,fp);        // ヘッダの読み出し
  301.     fclose(fp);
  302.     if (TIFF_getHead(databuf,DATABUF) < 0)
  303.         return -2;
  304.     int xlen,ylen,pixelsize,comp,fill;  long strip,clut;
  305.     if ((pixelsize = TIFF_checkMode(&xlen,&ylen,&comp,&fill,&strip,&clut)) < 0)
  306.         return -2;
  307.     info->xlen = xlen;
  308.     info->ylen = ylen;
  309.     info->compress = (comp == 1 ? NO : YES);
  310.     info->pixelsize = pixelsize;
  311.     return 0;
  312. }
  313.  
  314. /* end of tiff.c */
  315.